﻿using System;
using System.Collections.Generic;
using System.Linq;
using DataModel.Models;

namespace DataModel.Managers
{
    public class DepartmentManager
    {
        readonly UniversityPortalEntities _entityModel;

        public DepartmentManager()
        {
            _entityModel = new UniversityPortalEntities();
        }

        /// <summary>
        /// Create department
        /// </summary>
        /// <param name="shortName"></param>
        /// <param name="fullName"></param>
        /// <param name="description"></param>
        /// Exception: department with that name already exists
        public void CreateDepartment(string shortName, string fullName, string description)
        {
            if (_entityModel.Departments.Any(dp => dp.shortName == shortName))
            {
                throw new Exception(string.Format("Department {0} already exists", shortName));
            }

            var department = new Department
                {
                    ID = Guid.NewGuid(),
                    shortName = shortName,
                    fullName = fullName,
                    desription = description
                };

            _entityModel.AddToDepartments(department);
            _entityModel.SaveChanges();
        }

        /// <summary>
        /// Returns department global unique identifier
        /// </summary>
        /// <param name="shortName"></param>
        /// <returns></returns>
        ///  Exception: department with that name is not exists
        public Guid GetDepartamenGuid(string shortName)
        {
            Department department;
            try
            {
                department = _entityModel.Departments.First(departmentItem => departmentItem.shortName == shortName);
            }
            catch
            {
                throw new Exception(string.Format("Department with name \"{0}\" doesn't exist", shortName));
            }

            return department.ID;
        }


        public DepartmentModel GetDepartmentModel(Guid departmentID)
        {
            Department department = _entityModel.Departments.FirstOrDefault(departmentItem => departmentItem.ID == departmentID);
            if (department != null)
            {
                var departmentModel = new DepartmentModel
                    {
                        ShortName = department.shortName,
                        FullName = department.fullName,
                        Description = department.desription,
                        DepartmentID = department.ID
                    };
                var specManager = new SpecialityManager();
                foreach (var spec in department.Specialities)
                {
                    departmentModel.Specialities.Add(specManager.GetSpeciality(spec));
                }
                return departmentModel;
            }

            return null;
        }

        public Department GetDepartment(string shortName)
        {
            return _entityModel.Departments.FirstOrDefault(department => department.shortName == shortName);
        }

        public Department GetDepartment(string shortName, string fullName)
        {
            return _entityModel.Departments.First(department => (department.shortName == shortName) && (department.fullName == fullName));
        }

        public DepartmentModel GetDepartmentModel(Department department)
        {
            var departmentModel = new DepartmentModel
                {
                    Description = department.desription,
                    FullName = department.fullName,
                    ShortName = department.shortName,
                    DepartmentID = department.ID
                };
            var specialityManager = new SpecialityManager();
            foreach (var spec in department.Specialities)
            {
                departmentModel.Specialities.Add(specialityManager.GetSpeciality(spec));
            }
            return departmentModel;
        }

        public List<DepartmentModel> GetAllDepartments()
        {
            List<DepartmentModel> departmentModels = new List<DepartmentModel>();
            foreach (var department in _entityModel.Departments)
            {
                departmentModels.Add(GetDepartmentModel(department));
            }
            return departmentModels;
        }

        public void DeleteDepartment(Guid departmentID)
        {
            Department department;
            try
            {
                department = _entityModel.Departments.First(departmentItem => departmentItem.ID == departmentID);
            }
            catch
            {
                throw new Exception(string.Format("Department with ID \"{0}\" doesn't exist", departmentID.ToString()));
            }

            _entityModel.Departments.DeleteObject(department);
            _entityModel.SaveChanges();
        }

        public void DeleteDepartment(string shortName)
        {
            Department department;
            try
            {
                department = _entityModel.Departments.First(departmentItem => departmentItem.shortName == shortName);
            }
            catch
            {
                throw new Exception(string.Format("Department with name \"{0}\" doesn't exist", shortName));
            }

            _entityModel.Departments.DeleteObject(department);
            _entityModel.SaveChanges();
        }


        public void DeleteDepartment(string shortName, string fullName)
        {
            Department department;
            try
            {
                department = _entityModel.Departments.First(departmentItem => (departmentItem.shortName == shortName) && (departmentItem.fullName == fullName));
            }
            catch
            {
                throw new Exception(string.Format("Department with name \"{0} - {1}\" doesn't exist", shortName, fullName));
            }

            _entityModel.Departments.DeleteObject(department);
            _entityModel.SaveChanges();
        }

        public IEnumerable<SpecialityModel> GetDepartmentSpecialities(Guid departmentID)
        {
            return GetDepartmentModel(departmentID).Specialities.AsEnumerable();
        }
    }
}
